package NO1_Array;

/**
 * 2025-09-16
 * 力扣 - 79. 单词搜索
 * <p>
 * 给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中，返回 true ；否则，返回 false 。
 * 单词必须按照字母顺序，通过相邻的单元格内的字母构成，其中“相邻”单元格是那些水平相邻或垂直相邻的单元格。同一个单元格内的字母不允许被重复使用。
 */
public class ExistMain {
    public static void main(String[] args) {
        char[][] board = {{'A', 'B', 'C', 'E'}, {'S', 'F', 'C', 'S'}, {'A', 'D', 'E', 'E'}};
        String word = "ABCCED";
        System.out.println(exist(board, word));
    }

    public static boolean exist(char[][] board, String word) {
        int m = board.length;
        int n = board[0].length;

        // 遍历每个单元格作为起点
        for (int i = 0; i < m; i++) {
            for (int j = 0; j < n; j++) {
                if (backtrack(board, word, i, j, 0)) {
                    return true;
                }
            }
        }

        return false;
    }

    private static boolean backtrack(char[][] board, String word, int i, int j, int index) {
        // 如果已经匹配完所有字符，返回true
        if (index == word.length()) {
            return true;
        }

        // 检查边界条件和是否已访问
        if (i < 0 || i >= board.length || j < 0 || j >= board[0].length ||
                board[i][j] != word.charAt(index)) {
            return false;
        }

        // 标记当前单元格为已访问（用特殊字符标记）
        char temp = board[i][j];
        board[i][j] = '#';  // 标记为已访问

        // 四个方向进行DFS搜索
        boolean found = backtrack(board, word, i + 1, j, index + 1) ||  // 下
                backtrack(board, word, i - 1, j, index + 1) ||  // 上
                backtrack(board, word, i, j + 1, index + 1) ||  // 右
                backtrack(board, word, i, j - 1, index + 1);    // 左

        // 回溯：恢复单元格的原始值
        board[i][j] = temp;

        return found;
    }
}
